package cn.wolfcode.wolf2w.business.service.impl;

import cn.wolfcode.wolf2w.business.api.RemoteDestinationService;
import cn.wolfcode.wolf2w.business.api.domain.Note;
import cn.wolfcode.wolf2w.business.api.domain.NoteContent;
import cn.wolfcode.wolf2w.business.mapper.NoteContentMapper;
import cn.wolfcode.wolf2w.business.mapper.NoteMapper;
import cn.wolfcode.wolf2w.business.query.NoteQuery;
import cn.wolfcode.wolf2w.business.service.INoteService;
import cn.wolfcode.wolf2w.business.util.DateUtil;
import cn.wolfcode.wolf2w.common.core.constant.SecurityConstants;
import cn.wolfcode.wolf2w.common.core.context.SecurityContextHolder;
import cn.wolfcode.wolf2w.common.redis.service.RedisService;
import cn.wolfcode.wolf2w.common.redis.util.RedisKeys;
import cn.wolfcode.wolf2w.member.api.RemoteUserInfoService;
import cn.wolfcode.wolf2w.member.api.domain.UserInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;


/**
 * 旅游日记Service业务层处理
 *
 * @author 王南棕
 * @date 2025-09-15
  */
@Service
@Transactional
public class NoteServiceImpl extends ServiceImpl<NoteMapper,Note> implements INoteService {

    @Autowired
    private RemoteUserInfoService remoteUserInfoService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private RemoteDestinationService remoteDestinationService;
    @Autowired
    private NoteContentMapper noteContentMapper;

    @Override
    public void noteStatisHashPersistence() {
        //从redis中取出note数据
        Collection<String> keys = redisService.keys(RedisKeys.NOTE_STATIS_HASH.join("*"));
        if (keys!=null&keys.size()>0){
            for (String key : keys) {
                Map<String, Object> cacheMap = redisService.getCacheMap(key);
                lambdaUpdate().eq(Note::getId, Long.valueOf(cacheMap.get("id").toString()))
                        .set(Note::getViewnum,cacheMap.get("viewnum"))
                        .set(Note::getReplynum,cacheMap.get("replynum"))
                        .set(Note::getSharenum,cacheMap.get("sharenum"))
                        .set(Note::getFavornum,cacheMap.get("favornum"))
                        .set(Note::getThumbsupnum,cacheMap.get("thumbsupnum")).update();
            }
        }
    }
    @Override
    public IPage<Note> queryPage(NoteQuery qo) {
        IPage<Note> page = new Page<>(qo.getCurrentPage(), qo.getPageSize());
        LambdaQueryWrapper<Note> wrapper = new LambdaQueryWrapper<>();
        //判断排序
        if(qo.getOrderType() != null){
            if ("create_time".equals(qo.getOrderBy())){
                wrapper.orderByDesc(Note::getViewnum);
            }else {
                wrapper.orderByDesc(Note::getCreateTime);
            }
        }else{
            if ("create_time".equals(qo.getOrderBy())){
                wrapper.orderByDesc(Note::getCreateTime);
            }else {
                wrapper.orderByDesc(Note::getViewnum);
            }
        }

        // 判断出发时间类型
        if (qo.getTravelTimeType() != null &&qo.getTravelTimeType() != -1) {
            Long beginMonth = 1+2*(qo.getTravelTimeType()-1);
            Long endMonth = beginMonth+1;
            wrapper.apply("MONTH(travel_time) IN ("+beginMonth+", "+endMonth+")");
        }
        //人均消费
        if ( qo.getConsumeType() != null && qo.getConsumeType()!=-1){
            //1
            if (qo.getConsumeType()==1){
                wrapper.apply("avg_consume >= 1 AND avg_consume <= 999");
            }
            //2
            if (qo.getConsumeType()==2){
                wrapper.apply("avg_consume >= 1000 AND avg_consume <= 6000");
            }
            //3
            if (qo.getConsumeType()==3){
                wrapper.apply("avg_consume >= 6000 AND avg_consume <= 20000");
            }
            //4
            if (qo.getConsumeType()==4){
                wrapper.apply("avg_consume >= 20000");
            }
        }
        //出行天数
        if (qo.getDayType() != null &&  qo.getDayType()!=-1){
            //1
            if (qo.getDayType()==1){
                wrapper.apply("days <= 3");
            }
            //2
            if (qo.getDayType()==2){
                wrapper.apply("days >= 4 AND days <= 7");
            }
            //3
            if (qo.getDayType()==3){
                wrapper.apply("days >= 8 AND days <= 14");
            }
            //4
            if (qo.getDayType()==4){
                wrapper.apply("days >= 15");
            }
        }
        IPage<Note> noteIPage = baseMapper.selectPage(page, wrapper);
        noteIPage.getRecords().forEach(note -> {
            Long authorId = note.getAuthorId();
            UserInfo author = remoteUserInfoService.getOne(authorId, SecurityConstants.INNER).getData();
            note.setAuthor(author);
        });
        return noteIPage;
    }





    @Override
    @Transactional
    public void addNoteAndContent(Note note) {
        //添加note数据
        //1. 查询destId对应的destName
        String destName = remoteDestinationService.getOne(note.getDestId(), SecurityConstants.INNER).getData().getName();
        note.setDestName(destName);
        //2.查询作者id
        Long authorId = SecurityContextHolder.getUserId();
        note.setAuthorId(authorId);
        Date time = new Date();
        note.setCreateTime(time);
        note.setUpdateTime(time);
        //当前状态
        note.setStatus("0");
        this.baseMapper.insert(note);
        NoteContent noteContent = new NoteContent();
        noteContent.setId(note.getId());
        noteContent.setContent(note.getContent().getContent());
        noteContentMapper.insert(noteContent);
    }
    @Override
    public List<Note> viewnnumTop3(Long destId) {
        int limit = destId == null ? 5 : 3;
        return lambdaQuery()
                .orderByDesc(destId==null,Note::getCreateTime)
                .eq(destId!=null,Note::getDestId, destId)
                .last("limit "+limit)
                .list();
    }
    @Override
    public Map<String, Object> viewnumIncr(Long noteId) {
        String key = noteKeyHsahInit(noteId);
        redisService.incrementCacheMapValue(key, "viewnum", 1);
        return redisService.getCacheMap(key);
    }

    @Override
    public Boolean isUserFavor(Long nid, Long uid) {
        String key= RedisKeys.USER_NOTE_FAVOR.join(uid.toString());
        boolean a = redisService.isCacheSetContains(key, nid);
        return a;
    }

    @Override
    public Map<String, Object> star(Long nid) {
        //获取userid
        Long userId = SecurityContextHolder.getUserId();
        //根据userid和nid获取key
        String key = RedisKeys.USER_NOTE_THUMBSUP.join(userId.toString(), nid.toString());
        //计算过期时间
        Date now = new Date();
        Date end = DateUtil.getEndDate(now);
        long seconds = DateUtil.getDateBetween(now, end);
        if (!redisService.hasKey(key)){
            redisService.setCacheObject(key,0,seconds, TimeUnit.SECONDS);
        }
        //点赞次数
        Long num = redisService.incrementCacheObjectValue(key, 1);
        String hashkey = RedisKeys.NOTE_STATIS_HASH.join(nid.toString());
        boolean result = false;
        if (num<=3){
            result = true;
            redisService.incrementCacheMapValue(hashkey,"thumbsupnum",1);
        }
        Map<String, Object> cacheMap = redisService.getCacheMap(hashkey);
        cacheMap.put("result",result);
        return cacheMap;
    }


    private String noteKeyHsahInit (Long nid){
        String key = RedisKeys.NOTE_STATIS_HASH.join(nid.toString());
        //判断布隆过滤器后进行查询
        if (!redisService.hasKey(key)) {
            Note note = this.getById(nid);
            Map<String, Object> map = new HashMap<>();
            map.put("viewnum", Integer.valueOf(note.getViewnum().toString()));
            map.put("replynum", Integer.valueOf(note.getReplynum().toString()));
            map.put("sharenum", Integer.valueOf(note.getSharenum().toString()));
            map.put("favornum", Integer.valueOf(note.getFavornum().toString()));
            map.put("thumbsupnum", Integer.valueOf(note.getThumbsupnum().toString()));
            map.put("id", note.getId());
            redisService.setCacheMap(key, map);
        }
        return key;
    }
    @Override
    public Map<String, Object> collect(Long noteId) {
        //获取userid
        Long userId = SecurityContextHolder.getUserId();
        //根据userid获取key
        String key = RedisKeys.USER_NOTE_FAVOR.join(userId.toString());
        if (!redisService.hasKey(key)){
            Set<Long> set = new HashSet<>();
            set.add(-1L);
            redisService.setCacheSet(key, set);
        }
        //hash      15
        //key   12  1
        String hashkey = RedisKeys.NOTE_STATIS_HASH.join(noteId.toString());
        boolean b=false;
        if (redisService.isCacheSetContains(key, noteId)){
            b=false;
            redisService.incrementCacheMapValue(hashkey,"favornum",-1);
            redisService.deleteCacheSetValue(key, noteId);
        }else {
            b=true;
            redisService.incrementCacheMapValue(hashkey,"favornum",1);
            redisService.addCacheSetValue(key, noteId);
        }
        Map<String, Object> cacheMap = redisService.getCacheMap(hashkey);
        cacheMap.put("result",b);
        return cacheMap;
    }
}
